package com.milling.quartz.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.milling.business.BusinessConstants;
import com.milling.business.GlobalVariable;
import com.milling.business.domain.*;
import com.milling.business.mapper.WmsNeedleCacheMapper;
import com.milling.business.service.*;
import com.milling.business.service.impl.WmsConfigHoleServiceImpl;
import com.milling.common.core.redis.RedisCache;
import com.milling.common.utils.SocketUtils;
import com.milling.common.utils.StringUtils;
import com.milling.common.utils.modbus.ModbusMasterPoolFactory;
import com.milling.common.utils.modbus.ModbusServiceFactory;
import com.milling.common.utils.modbus.ModbusTcpService;
import com.milling.common.utils.modbus.ModbusTcpServiceImpl;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import org.apache.commons.pool2.ObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

//上料服务XXXXXXXXX
@Configuration
@ConditionalOnProperty(
        name = "mac.type",
        havingValue = "1",
        matchIfMissing = false // 当配置缺失时不加载
)
@Component
public class FetchTasks {

    private static final Logger logger = LoggerFactory.getLogger(FetchTasks.class);

    @Value("${wcs.tcp.macCode}")
    private String macCode; // 从配置文件或命令行参数中读取

    // 从参数中读取IP、端口、slaveId和连接池大小
    @Value("${modbus.tcp.host:192.168.237.88}") // 默认值防止未配置
    private String host;

    @Value("${modbus.tcp.port:502}")
    private int port;

    @Value("${modbus.tcp.poolSize:5}")
    private int poolSize;

    @Value("${modbus.tcp.slaveId:1}")
    private int slaveId;

    @Value("${config.ip}")
    private String configIp;

    @Value("${config.port}")
    private int configPort;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IWmsCellInfoService wmsCellInfoService;

    @Autowired
    private IWmsTaskInfoService wmsTaskInfoService;

    @Autowired
    private WmsNeedleCacheMapper wmsNeedleCacheMapper;

    @Autowired
    private IWmsConfigSubService wmsConfigSubService;

    private IWmsTxnInfoService wmsTxnInfoService;

    @Autowired
    private IWmsNeedleCacheService wmsNeedleCacheService;

    @Autowired
    private IWmsConfigInfoService wmsConfigInfoService;

    @Autowired
    private IWmsBoxInfoService wmsBoxInfoService;

    @Autowired
    private IWmsBoxHoleService wmsBoxHoleService;
//    private WmsBoxInfoServiceImpl wmsBoxInfoServiceImpl;

    // 获取Modbus服务实例
    private ModbusTcpService modbusTcpService;
    @Autowired
    private WmsConfigHoleServiceImpl wmsConfigHoleServiceImpl;

//    @Autowired
//    private ModbusUtil modbusUtil;

    @PostConstruct
    public void init() {
        // 初始化 Modbus 服务
        modbusTcpService = ModbusServiceFactory.getModbusService(host, port, poolSize);
        logger.info("FetchTasks Modbus服务初始化完成 - {}:{}", host, port);

        // 初始化扫码器连接
//        initConnection();
    }

    // 每500毫秒执行一次
    @Scheduled(fixedRate = 500)
    public void executeTask() {
        // 这里添加你的业务逻辑
//        logger.info("定时任务执行，间隔0.5秒");

        // 创建连接池
//        ObjectPool<ModbusMaster> modbusMasterPool = ModbusMasterPoolFactory.createPool(host, port, poolSize);
//        ModbusTcpService modbusTcpService = new ModbusTcpServiceImpl(modbusMasterPool);

        try {
//            int registerAddress = 550;
            int startAddress = 499;
            int numberOfRegisters = 25;

            // 示例：读取单个保持寄存器
            short[] numbers = new short[numberOfRegisters];
            // 示例：读取多个保持寄存器
            short[] values = modbusTcpService.readHoldingRegisters(slaveId, startAddress, numberOfRegisters);
            for (int i = 0; i < values.length; i++) {
                if(values[i] > 0) {//需要复位
                    onRegisterChange(startAddress + i);
                }
            }
        } catch (Exception e) {
            logger.error("读取寄存器地址  失败");
            e.printStackTrace();
//        } finally {
//            // 关闭连接池
//            modbusMasterPool.close();
        }
    }

    public void onRegisterChange(int registerAddress) {
//        log.info("Register {} changed from {} to {}", registerAddress, oldValue, newValue);
//        logger.info("寄存器 {} 为 1", registerAddress);
        try {
            switch (registerAddress) {
                case 501:
                    int startValue = modbusTcpService.readHoldingRegister(slaveId, 501);
//                    GlobalVariable.plc501Value = startValue;
                    // 写Redis代替静态变量
                    redisCache.setCacheObject(GlobalVariable.PLC_501_VALUE, startValue);
/*
                    if(startValue == 0) {
                        GlobalVariable.startValue = startValue;
                    } else if(startValue == 1 && GlobalVariable.startValue < 1) {
                        GlobalVariable.startValue = GlobalVariable.startValue + 1;
                        wmsTaskInfoService.feedingFull();
                    } else {
                        GlobalVariable.startValue = 5;
                    }
*/
                    // 读取Redis值
                    Integer globalStartValue = redisCache.getCacheObject(GlobalVariable.START_VALUE);
                    if (startValue == 0) {
                        redisCache.setCacheObject(GlobalVariable.START_VALUE, 0);
                    } else if (startValue == 1 && (globalStartValue == null || globalStartValue < 1)) {
                        redisCache.setCacheObject(GlobalVariable.START_VALUE, globalStartValue != null ? globalStartValue + 1 : 1);
                        wmsTaskInfoService.feedingFull();
                    } else {
                        redisCache.setCacheObject(GlobalVariable.START_VALUE, 5);
                    }
                    break;
                case 502://由503地址清0
                    int startValue2 = modbusTcpService.readHoldingRegister(slaveId, 502);

//                    GlobalVariable.plc502Value = startValue2;
                    redisCache.setCacheObject(GlobalVariable.PLC_502_VALUE, startValue2);
//                    handleRegisterChange(modbusTcpService, registerAddress, "PLC通知PC上/下料机械手已到安全位置");
//XXXX              PLC通知PC上/下料机械手已到安全位置	1 完成，0未完成，由PC进行清零。
                    break;
//AAA                case 503:
                //写入 1 - 16针盒ID，并对502清0
//AAA                    modbusTcpService.writeHoldingRegister(1, 502, 0);
//                    handleRegisterChange(modbusTcpService, registerAddress, "PC接收到WCS送整盒到达后，通知PLC取针并放入上料托盘ID号");
//XXXX                    D503	PC接收到WCS送整盒到达后，通知PLC取针并放入上料托盘ID号	PC并对D502进行清0，ID号是上料托盘16个针盒的ID，从左到右依次排序
//AAA                    break;
                case 504://504清0，并判断是否可以告知PLC整盒配完 505
                    handleRegisterChange(modbusTcpService, registerAddress, "PLC通知PC,当前50支针插入上料托盘ID号OK");
                    wmsTaskInfoService.write505();
//XXXX                    D504	PLC通知PC,当前50支针插入上料托盘ID号OK，PLC并对D503进行清0	1完成 0未完成，PC接收到完成之后由PC对此地址进行清0
                    break;
                case 506://PC不处理这个地址的值，写入配散针信息  PLC通知PC上料托盘到达中间配针位置	1到位 0未到位,一旦离开中间区域，PLC对此进行清0
//                    handleRegisterChange(modbusTcpService, registerAddress, "PC通知PLC是左还是右托盘配针，PLC接收到后，继续进行配针动作");
//XXXX                    D506	PLC通知PC上料托盘到达中间配针位置	1到位 0未到位,一旦离开中间区域，PLC对此进行清0
                    int writeTayData = modbusTcpService.readHoldingRegister(slaveId, 506);
                    if( writeTayData == 1) {
                        /*if (!GlobalVariable.writeHolesFlag) {
                            logger.info("扫码针盒数" + GlobalVariable.CONFIG_BOX_ID);
                            for (int i = 0; i < GlobalVariable.CONFIG_BOX_CODE.length; i++) {
                                logger.info("针盒" + i + " 码 " + GlobalVariable.CONFIG_BOX_CODE[i]);
                            }

                            wmsTaskInfoService.write800();
                            GlobalVariable.writeHolesFlag = true;
                        }*/
                        // 从Redis读取标志位
                        Boolean writeHolesFlag = redisCache.getCacheObject(GlobalVariable.WRITE_HOLES_FLAG);
                        if (writeHolesFlag == null || !writeHolesFlag) {
                            // 记录日志
                            redisCache.setCacheObject(GlobalVariable.WRITE_HOLES_FLAG, true);
                            wmsTaskInfoService.write800();
                        }
                    }
                    break;
                case 507://16个盒子扫码动作
                    int boxId = modbusTcpService.readHoldingRegister(slaveId,507);

                    // 检查是否正在扫码中
                    String scanningKey = "scanning:status:" + boxId;
                    Boolean isScanning = redisCache.getCacheObject(scanningKey);
                    if (isScanning != null && isScanning) {
                        logger.info("扫码进行中，跳过boxId: {}", boxId);
                        break;
                    }

                    logger.info("boxId： {}", boxId);
                    if(boxId > 0 && boxId < 17) {
                        // 设置扫码状态标志，有效期5秒
                        redisCache.setCacheObject(scanningKey, true, 5, TimeUnit.SECONDS);
//                        GlobalVariable.CONFIG_BOX_ID = boxId;
                        redisCache.setCacheObject(GlobalVariable.CONFIG_BOX_ID, boxId);
                        logger.error("扫码任务，正在扫码第 {} 个boxId", boxId);

                        try {
                            // 异步执行扫码任务

                            CompletableFuture.runAsync(() -> {
                                try (SocketUtils socketUtils = new SocketUtils(configIp, configPort)) {
                                    socketUtils.sendMessage("start");
                                    Thread.sleep(50); // 添加短暂延迟
                                } catch (Exception e) {
                                    logger.error("扫码异常 boxId: {}", boxId, e);
                                    try {
                                        modbusTcpService.writeHoldingRegister(slaveId, 507, 100);
                                    } catch (ModbusTransportException ex) {
                                        logger.error("写PLC失败", ex);
                                    }
                                } finally {
                                    // 清除扫码状态
                                    redisCache.deleteObject(scanningKey);
                                }
                            });
                        } catch (Exception e) {
                            logger.error("启动扫码任务失败", e);
                            redisCache.deleteObject(scanningKey);
                            modbusTcpService.writeHoldingRegister(slaveId, 507, 100);
                        }

                        /*try {
                            //扫码
                            SocketUtils socketUtils = new SocketUtils(configIp, configPort);
                            socketUtils.sendMessage("start");
                            socketUtils.disconnect();
                            socketUtils.destroy();
//                            Thread.sleep(5);
                        } catch (Exception e) {
                            e.printStackTrace();
                            logger.error("ConfigScanner sendMessage Fail");
                            modbusTcpService.writeHoldingRegister(slaveId, 507, 100);
                        }*/
                    }

//                    handleRegisterChange(modbusTcpService, registerAddress, "PC通知PLC是左还是右托盘配针，PLC接收到后，继续进行配针动作");
//XXXX                    D507	上料托盘到达位置后，PLC通知PC扫码针盒(1-12)	1-16为上料托盘中的针盒ID号,扫码分析后，分析OK，PC清0，直到第12次分析。如果PC扫码分析NG，PC通知PLC(100),并触发报警信息，PC弹出报警提示人工更换针盒,人工更换针盒OK后,点击确定,PLC再次触发扫码信号，此信号的ID要和NG前的ID一致，以保证是当前NG后更换的针盒ID，PC再根据PLC的扫码信号进行拍照分析，直至OK。
                    break;
                case 509:
//                    handleRegisterChange(modbusTcpService, registerAddress, "PC通知PLC是左还是右托盘配针，PLC接收到后，继续进行配针动作");
//XXXX                 D509	PC通知PLC，中间配针数据已经分配OK，可以进行配针	1为进行配针,0为不可以,PLC开始进行配针，配针结束后PLC对此地址进行清0
//XXXX                 PC逻辑运算，当前存针区钻针类型是否完全匹配配针托盘，如果不匹配,则会呼叫WMS送针	PC与WMS进行交互
                    break;
                case 511://补料到位，PC要改 510 地址 的值
                    handleRegisterChange(modbusTcpService, registerAddress, "PLC取针放目的地存料托盘ID后，通知PC已取针OK");
                    wmsTaskInfoService.process511();
                    break;
//                D511	PLC取针放目的地存料托盘ID后，通知PC已取针OK	1完成 0未完成，由PC进行清0
                case 512:
                    WmsTaskInfo wmsTaskInfo5 = new WmsTaskInfo();
                    wmsTaskInfo5.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                    wmsTaskInfo5.setFullType(BusinessConstants.FULL_TYPE_MIX);
                    wmsTaskInfo5.setTaskType(BusinessConstants.TASK_TYPE_2);
                    List<WmsTaskInfo> wmsTaskInfos2 = wmsTaskInfoService.selectWmsTaskInfoList(wmsTaskInfo5);
                    if(wmsTaskInfos2 != null && wmsTaskInfos2.size() > 0) {
                        modbusTcpService.writeHoldingRegister(slaveId, 512, 0);//回流任务，直接清0
                        return;
                    }
                    /// ///////////  start  /////////////
                    WmsTaskInfo wmsTaskInfoQ = new WmsTaskInfo();
                    wmsTaskInfoQ.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                    wmsTaskInfoQ.setFullType(BusinessConstants.FULL_TYPE_MIX);
                    List<WmsTaskInfo> wmsTaskInfosQ = wmsTaskInfoService.selectWmsTaskInfoList(wmsTaskInfoQ);
                    if(wmsTaskInfosQ != null && wmsTaskInfosQ.size() > 0) {
                        WmsTaskInfo wmsTaskInfoX = wmsTaskInfosQ.get(0);
                        if(getTray() == 1) {//左配针
                            if (wmsTaskInfoX.getPortId() != null && wmsTaskInfoX.getPortId().intValue() == 2) {
                                logger.debug("左补针进行中，等待... ...");
                                handleRegisterChange(modbusTcpService, registerAddress, "PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成");
                                return;
                            }
                        } else if(getTray() == 2) {//右配针
                            if (wmsTaskInfoX.getPortId() != null && wmsTaskInfoX.getPortId().intValue() == 1) {
                                logger.debug("右补针进行中，等待... ...");
                                handleRegisterChange(modbusTcpService, registerAddress, "PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成");
                                return;
                            }
                        }
                    }

                    WmsConfigSub wmsConfigSub2 = new WmsConfigSub();
                    wmsConfigSub2.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);
                    List<WmsConfigSub> wmsConfigSubs2 = wmsConfigSubService.selectWmsConfigSubList(wmsConfigSub2);

                    if (null != wmsConfigSubs2 && wmsConfigSubs2.size() > 0) {
                        wmsConfigSub2 = wmsConfigSubs2.get(0);
                    }
                    Boolean bFlag = wmsConfigInfoService.mixHalf(wmsConfigSub2.getConfigSubId());
                    if(bFlag) {//需要切托盘后继续补料
                        int leftFeedPosition = modbusTcpService.readHoldingRegister(slaveId, 570);
                        int rightFeedPosition = modbusTcpService.readHoldingRegister(slaveId, 571);

                        if(rightFeedPosition == 1) {//右补料
                            modbusTcpService.writeHoldingRegister(slaveId, 508, 1);//切换配针托盘
                            redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
                            modbusTcpService.writeHoldingRegister(slaveId, 571, 0);//切换配针托盘
                            handleRegisterChange(modbusTcpService, registerAddress, "PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成");
                        } else if (leftFeedPosition == 1) {//左补料
                            modbusTcpService.writeHoldingRegister(slaveId, 508, 2);//切换配针托盘
                            redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
                            modbusTcpService.writeHoldingRegister(slaveId, 570, 0);//切换配针托盘
                            handleRegisterChange(modbusTcpService, registerAddress, "PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成");
                        } else {
                            WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
                            wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                            wmsTaskInfo.setFullType(BusinessConstants.FULL_TYPE_MIX);
                            List<WmsTaskInfo> wmsTaskInfos = wmsTaskInfoService.selectWmsTaskInfoList(wmsTaskInfo);
                            if (wmsTaskInfos.size() > 0) {
                                //有补针任务，不处理，等待 570 / 571 信号
//                            logger.info("有补针任务，不处理，等待 570 / 571 信号");
                            } else {
                                wmsTaskInfoService.process512();
                            }
                        }
                    }

                    /// ///////////   end   ////////////

/*                  移动到 bFlag 条件块中
                    int leftFeedPosition = modbusTcpService.readHoldingRegister(slaveId, 570);
                    int rightFeedPosition = modbusTcpService.readHoldingRegister(slaveId, 571);

                    if(rightFeedPosition == 1) {//右补料
                        modbusTcpService.writeHoldingRegister(slaveId, 508, 1);//切换配针托盘
                        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
                        modbusTcpService.writeHoldingRegister(slaveId, 571, 0);//切换配针托盘
                        handleRegisterChange(modbusTcpService, registerAddress, "PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成");
                    } else if (leftFeedPosition == 1) {//左补料
                        modbusTcpService.writeHoldingRegister(slaveId, 508, 2);//切换配针托盘
                        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
                        modbusTcpService.writeHoldingRegister(slaveId, 570, 0);//切换配针托盘
                        handleRegisterChange(modbusTcpService, registerAddress, "PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成");
                    } else {
                        WmsTaskInfo wmsTaskInfo = new WmsTaskInfo();
                        wmsTaskInfo.setTaskStatus(BusinessConstants.TASK_STATUS_2);
                        wmsTaskInfo.setFullType(BusinessConstants.FULL_TYPE_MIX);
                        List<WmsTaskInfo> wmsTaskInfos = wmsTaskInfoService.selectWmsTaskInfoList(wmsTaskInfo);
                        if (wmsTaskInfos.size() > 0) {
                            //有补针任务，不处理，等待 570 / 571 信号
//                            logger.info("有补针任务，不处理，等待 570 / 571 信号");
                        } else {
                            wmsTaskInfoService.process512();
                        }
                    }
*/
                    break;
//                D512	PLC中间左或右配针完成时通知PC，当前左/右存针区托盘已经配针完成	1完成 0未完成，由PC进行清0
                case 514:
                    int configTrayComplete = modbusTcpService.readHoldingRegister(slaveId, registerAddress);
                    if(configTrayComplete == 1) {
                        //判断是否需要切托盘后再补料
                        /*WmsConfigSub wmsConfigSubQuery = new WmsConfigSub();
                        wmsConfigSubQuery.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);
                        List<WmsConfigSub> wmsConfigSubs = wmsConfigSubService.selectWmsConfigSubList(wmsConfigSubQuery);
                        if(null != wmsConfigSubs && wmsConfigSubs.size() > 0) {
                            WmsConfigSub wmsConfigSub = wmsConfigSubs.get(0);
                            Boolean bFlag = wmsConfigInfoService.mixHalf(wmsConfigSub.getConfigSubId());
                            if(bFlag) {//需要切托盘后继续补料
                                try {
                                    if (getTray() == 1) {
                                        modbusTcpService.writeHoldingRegister(slaveId, 508, 2);//切换配针托盘
                                        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 2);
                                    } else if (getTray() == 2) {
                                        modbusTcpService.writeHoldingRegister(slaveId, 508, 1);//切换配针托盘
                                        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 1);
                                    }
                                } catch (ModbusTransportException e) {
                                    e.printStackTrace();
                                    logger.error("补料过半，切托盘 失败");
                                }
                            }
                        }*/

                        //如果有下一个托盘，则重新生成整盒任务以及800空位数据
//                    D514	PLC通知PC,当前配针托盘是否全部配置OK	1完成，0未完成，后进行下料动作，并且根据状态进行选择是否，下一个配针托盘上料动作。由PC进行清零。
                        handleRegisterChange(modbusTcpService, registerAddress, "PLC通知PC,当前配针托盘是否全部配置OK");
//                        WmsConfigInfo
                        //启动下一个托盘的配针任务
                    }
                    break;
                case 515:
                    try {
                        int trayCount = modbusTcpService.readHoldingRegister(slaveId, 515);
                        logger.info("PLC通知PC托盘下料完成：" + trayCount);
                        handleRegisterChange(modbusTcpService, registerAddress, "PLC通知PC托盘下料完成");
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.error("获取 PLC通知PC的托盘下料总数异常");
                        return;
                    }

                    WmsConfigSub wmsConfigSub = new WmsConfigSub();
                    wmsConfigSub.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_CONFIGING);
                    List<WmsConfigSub> wmsConfigSubs = wmsConfigSubService.selectWmsConfigSubList(wmsConfigSub);
                    WmsConfigSub wmsConfigSubDB = wmsConfigSubs.get(0);
//                    for (int i = 0; i < GlobalVariable.CONFIG_BOX_CODE.length; i++) {
                    String boxDatas = wmsConfigSubDB.getConfigSubContent();
                    JSONArray jsonArray = JSONArray.parseArray(boxDatas);

                    // 从Redis获取整个数组
//                    List<String> configBoxList = redisCache.getCacheList(GlobalVariable.CONFIG_BOX_CODE);
//                    for (int i = 0; i < configBoxList.size(); i++) {
//                        logger.info("515 configBoxList:{}", configBoxList.get(i));
//                    }
                    Map<String, String> configBoxCodes = redisCache.getCacheMap(GlobalVariable.CONFIG_BOX_CODE);

                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        String boxType = jsonObject.getString("boxType");
                        if (!"EMPTY".equals(boxType)) {
//                            String boxCode = GlobalVariable.CONFIG_BOX_CODE[i];
                            // 从数组获取值
//                            String boxCode = configBoxList.get(i);
//                            configBoxCodes.put("BOXID-" + boxId, message);

                            // 修复索引问题：扫码时存储的key是从1开始的，这里需要+1
                            String boxCode = configBoxCodes.get("BOXID-" + String.valueOf(i + 1));

                            WmsBoxInfo wmsBoxInfo = new WmsBoxInfo();
                            wmsBoxInfo.setBoxData(jsonObject.toString());
                            wmsBoxInfo.setBoxCode(boxCode);
                            wmsBoxInfo.setCreateTime(new Date());
                            wmsBoxInfo.setBoxStatus("0");//配针
                            if("MIX".equals(boxType)) {
                                wmsBoxInfo.setSameFlag("2");//混装
                            } else if("FULL".equals(boxType)) {
                                wmsBoxInfo.setSameFlag("1");//整盒
                            }
                            wmsBoxInfo.setRemark(wmsConfigSubDB.getConfigId().toString());
                            wmsBoxInfoService.insertWmsBoxInfo(wmsBoxInfo);
/// ////////////////记录配针各盒子孔位信息start
                            //记录插针数据
                            List<WmsBoxHole> wmsBoxHoles = new ArrayList<>();
                            String drillInfos = jsonObject.getString("drillInfos");
                            if("MIX".equals(boxType)) {
                                //混料
                                String[] drillInfoArray = drillInfos.split(",");
                                for (int j = 0; j < drillInfoArray.length; j++) {
                                    WmsBoxHole wmsBoxHole = new WmsBoxHole();
                                    String drillinfo = drillInfoArray[j];
                                    Long holeid = j + 1L;
                                    wmsBoxHole.setHoleId(holeid);
                                    wmsBoxHole.setDrillInfo(drillinfo.trim());
                                    wmsBoxHole.setBoxId(wmsBoxInfo.getId());
                                    wmsBoxHole.setSortStatus("0");
                                    wmsBoxHole.setConfigStatus("2");
                                    wmsBoxHole.setCreateTime(new Date());
                                    wmsBoxHoles.add(wmsBoxHole);
                                }
                            } else if("FULL".equals(boxType)) {
                                logger.info("整盒数据，不做处理了......" + boxCode);
                                //没有整盒，不处理了
//                                wmsBoxInfo.setSameFlag("1");//整盒
                            }

                            for (int m = 0; m < wmsBoxHoles.size(); m++) {
                                wmsBoxHoleService.insertWmsBoxHole(wmsBoxHoles.get(m));
                            }
                            logger.info("盒子 {} 的孔位数据记录成功" , boxCode);
/// ////////////////记录配针各盒子孔位信息end

                            //同步PLC的配针孔位数据
                            wmsConfigInfoService.syncPlcDrills(wmsConfigSubDB.getConfigSubId());
                            logger.info("同步PLC的配针孔位数据完成");

                            // 增强日志输出，便于调试
                            if (StringUtils.isNotEmpty(boxCode)) {
                                logger.info("成功保存盒子信息 - 索引: {}, 二维码: {}, 类型: {}", i + 1, boxCode, boxType);
                            } else {
                                logger.warn("警告：盒子信息二维码为空 - 索引: {}, 类型: {}, 检查Redis key: BOXID-{}", i + 1, boxType, i + 1);
                            }
                        }
                    }
//                    }


                    wmsConfigSubDB.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_COMPLETE);
                    wmsConfigSubService.updateWmsConfigSub(wmsConfigSubDB);

                    //是否还有尚未配针的托盘
                    wmsConfigSub.setConfigSubStatus(BusinessConstants.CONFIG_STATUS_UNCONFIG);
                    wmsConfigSub.setConfigId(wmsConfigSubDB.getConfigId());
                    wmsConfigSubs = wmsConfigSubService.selectWmsConfigSubList(wmsConfigSub);
                    if(null != wmsConfigSubs && wmsConfigSubs.size() > 0){
                        logger.info("继续配针");
                        wmsNeedleCacheService.sysncNeedleStatus();
                        //启动新托盘任务
                        //522地址写入1，继续配针，无需处理启动地址
                        modbusTcpService.writeHoldingRegister(slaveId, 522, 1);
//                        GlobalVariable.initConfigParam();
                        wmsConfigInfoService.initConfigParam();
                        //启动配针子工单
                        wmsConfigInfoService.startConfigTask(macCode, wmsConfigSubs.get(0));
                        //初始化，重新初始化全局变量
                    } else {
                        logger.info("结束配针任务");
                        //结束配针任务 - 修改为用户选择是否继续配针
                        //522地址写入2，结束配针
                        //此工单已配完，询问是否开启下一个工单的配置任务
                        //用户选择 是：执行初始化动作，初始化参数，获取最优先的配针工单，启动配针任务
                        //用户选择 否：结束配针任务，并刷新配针看板
                        WmsConfigInfo wmsConfigInfo = wmsConfigInfoService.selectWmsConfigInfoByConfigId(wmsConfigSubDB.getConfigId());
                        wmsConfigInfo.setConfigStatus(BusinessConstants.CONFIG_STATUS_COMPLETE);
                        wmsConfigInfoService.updateWmsConfigInfo(wmsConfigInfo);
                        modbusTcpService.writeHoldingRegister(slaveId, 522, 2);
                    }
                    //                    handleRegisterChange(modbusTcpService, registerAddress, "PLC通知PC托盘下料完成");
//                    D515	PLC通知PC托盘下料完成	1 完成，0未完成，由PC进行清零。
                    break;
                case 516:
                    int boxCount = modbusTcpService.readHoldingRegister(slaveId,516);
                    logger.info("PLC通知PC下料针盒数\t当 D515 >= N 时，PLC禁止下料，处理完成后PC进行清零，总下料" + boxCount +"盒");
                    modbusTcpService.writeHoldingRegister(slaveId, 516, 0);
//                    handleRegisterChange(modbusTcpService, registerAddress, "PLC通知PC下料针盒数");
//                    D516	PLC通知PC下料针盒数	当 D515 >= N 时，PLC禁止下料，处理完成后PC进行清零
                    break;
                case 518:
                    handleRegisterChange(modbusTcpService, registerAddress, "已将回流ID放入针盒");
                    WmsNeedleCache wmsNeedleCache1 = new WmsNeedleCache();
                    wmsNeedleCache1.setStatus(BusinessConstants.NEEDLE_STATUS_3);
                    List<WmsNeedleCache> wmsNeedleCaches = wmsNeedleCacheMapper.selectWmsNeedleCacheList(wmsNeedleCache1);
                    for (int i = 0; i < wmsNeedleCaches.size(); i++) {
                        WmsNeedleCache wmsNeedleCache = wmsNeedleCaches.get(i);
                        wmsNeedleCache.setStatus(BusinessConstants.NEEDLE_STATUS_1);
                        wmsNeedleCache.setDrillSize(null);
                        wmsNeedleCache.setDrillInfo(null);
                        wmsNeedleCache.setDrillType(null);
                        wmsNeedleCache.setDrillEdge(null);
                        wmsNeedleCache.setDrillFactory(null);
                        wmsNeedleCache.setDrillGrindCount(null);
                        wmsNeedleCache.setDrillCount(new Long(0));
                        wmsNeedleCacheMapper.updateWmsNeedleCache(wmsNeedleCache);
                    }
                    break;
                case 521:
                    handleRegisterChange(modbusTcpService, registerAddress, "PLC通知PC当前料号已全配置完成，等待PC回复");
//                    D521	PLC通知PC当前料号已全配置完成，等待PC回复	0未完成，1完成等待PC发送信号；信号合并模式:2则通知继续，3则通知结束
                    break;
            }
        } catch (ModbusTransportException e) {
            e.printStackTrace();
            logger.error("写入寄存器地址 "+registerAddress+" 失败");
//            throw new RuntimeException(e);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理寄存器变化逻辑
     *
     * @param modbusTcpService Modbus TCP 服务
     * @param registerAddress  寄存器地址
     * @param description     寄存器描述
     * @throws ModbusTransportException Modbus通信异常
     */
    private void handleRegisterChange(ModbusTcpService modbusTcpService, int registerAddress, String description)
            throws ModbusTransportException {
        modbusTcpService.writeHoldingRegister(slaveId, registerAddress, 0);
        logger.info("Handled register address {}: {}", registerAddress, description);
    }

    private void initConfig() {
/*
        GlobalVariable.plc501Value = 0;
        GlobalVariable.startValue = 0;
        GlobalVariable.writeHolesFlag = false;
        GlobalVariable.plc502Value = 0;
        GlobalVariable.CONFIG_TRAY = 0;
        GlobalVariable.CONFIG_BOX_ID = 0;
        GlobalVariable.CONFIG_BOX_CODE = new String[16];
*/
        redisCache.setCacheObject(GlobalVariable.PLC_501_VALUE, 0);
        redisCache.setCacheObject(GlobalVariable.START_VALUE, 0);
        redisCache.setCacheObject(GlobalVariable.WRITE_HOLES_FLAG, false);
        redisCache.setCacheObject(GlobalVariable.PLC_502_VALUE, 0);
        redisCache.setCacheObject(GlobalVariable.CONFIG_TRAY, 0);
        redisCache.setCacheObject(GlobalVariable.CONFIG_BOX_ID, 0);

        // 初始化数组 - 使用List存储
        List<String> emptyList = Arrays.asList(new String[16]);
        redisCache.setCacheList(GlobalVariable.CONFIG_BOX_CODE, emptyList);
    }

    private int getTray() {
        return getIntCache(GlobalVariable.CONFIG_TRAY);
    }

    private int getIntCache(String key) {
        return redisCache.getCacheObject(key) == null ? 0 : (int) redisCache.getCacheObject(key);
    }

}
